/*
    同步 echo server
*/


#include <iostream>
#include <boost/asio.hpp>
#include <thread>
#include <memory>
#include <set>

#include "threadPool.hpp"

const int max_length = 1024;
using socket_ptr = std::shared_ptr<boost::asio::ip::tcp::socket>;
CThreadPool pool;


void session(socket_ptr socket)
{
    try
    {
        while(true)
        {
            char data[max_length];
            memset(data, 0, max_length);
            boost::system::error_code error;
            auto len = socket->read_some(boost::asio::buffer(data, max_length), error);
            if(error == boost::asio::error::eof)
            {
                std::cout << "Connection closed by client" << std::endl;
                break;
            }
            else if(error)
            {
                throw std::runtime_error("read failed: " + error.message());
            }
            
            std::cout << "Received from client: " << socket->remote_endpoint().address().to_string() << std::endl;
            std::cout << "Received: " << data << std::endl;

            boost::asio::write(*socket, boost::asio::buffer(data, len));
            
        }
    }
    catch (const std::exception& e)
    {
        std::cout << "Exception: " << e.what() << std::endl;
        return;
    }
}

void server(boost::asio::io_context& io_context, uint16_t port)
{
    using tcp = boost::asio::ip::tcp;
    tcp::acceptor a(io_context, tcp::endpoint(tcp::v4(), port));
    std::cout << "Server started on port: " << port << std::endl;

    while(true)
    {
        socket_ptr socket = std::make_shared<tcp::socket>(io_context);
        a.accept(*socket);
        pool.EnQueue(session, socket);
    }
}


int main()
{
    try
    {
        boost::asio::io_context io_context;
        server(io_context, 12345);
        pool.Stop();
    }
    catch (const std::exception& e)
    {
        std::cout << "Exception: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}